package me.zhengjie.domain;

import cn.hutool.core.util.ObjectUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.config.RegisterAddressConfig;
import me.zhengjie.dto.CacheRackInfo;
import me.zhengjie.dto.NotAssignedOrderInfo;
import me.zhengjie.dto.sqlServer.*;
import me.zhengjie.modbusTCP.LogisticsAreaTCP;
import me.zhengjie.repository.*;
import me.zhengjie.util.UniqueCodeUtil;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Column;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class UnbindingService {
    private final InventoryRepository inventoryRepository;
    private final PalletRepository palletRepository;
    private final UnbindingOrderRepository unbindingOrderRepository;
    private final UnbindingOrderDetailRepository unbindingOrderDetailRepository;
    private final UnbindingStationRepository unbindingStationRepository;
    private final PinlaminationunloadOneRepository pinlaminationunloadOneRepository;
    private final PinlaminationunloadTwoRepository pinlaminationUnloadTwoRepository;
    private final LogisticsAreaTCP logisticAreaTCP;
    private final PressMachineRepository pressMachineRepository;
    private final ProcesscardRepository processcardRepository;


    /**
     * 解绑载盘和工艺卡
     */
    public Inventory getInventoryMsg(String palletCode) {
        // 根据载盘码获取库存信息
        int palletId = palletRepository.findPalletByPalletCode(palletCode).getId();
        //
        return inventoryRepository.findById(palletId).get();
    }

    @Transactional
    public void unbinding(String palletCode) {
        // 更新载盘表数据,清空绑定信息
        palletRepository.unbindingPalletAndProcessCard(palletCode);
    }

    /**
     * 在出压口根据压机id和载盘码分配或创建出库单
     *
     * @param scannerValue   载盘码
     * @param pressMachineId 压机id
     */
    public void createOrderOrJoinOrder(String scannerValue, Integer pressMachineId) throws Exception {
        Integer potId = null;
        UnbindingOrder unbindingOrder = null;

        // 根据压机 ID 获取 potId
        if (pressMachineId.equals(1)) {
            List<PinlaminationunloadOne> pinlaminationunloadOneList = pinlaminationunloadOneRepository.findPinlaminationunloadOneByBarcodeNumber(scannerValue);

            if (pinlaminationunloadOneList != null && !pinlaminationunloadOneList.isEmpty()) {
                {
                    potId = pinlaminationunloadOneList.get(0).getPotId();
                    // 如果 potId 为空，直接抛出异常
                    if (ObjectUtil.isEmpty(potId)) {
                        throw new Exception();
                    }

                    // 查询拆解单
                    unbindingOrder = unbindingOrderRepository.findUnbindingOrderByPotIdAndPressMachineId(potId,pressMachineId);

                    if (ObjectUtil.isEmpty(unbindingOrder)) {
                        //一次性生成完整拆解单
                        List<PinlaminationunloadOne> pinlaminationunloadOnePotList = pinlaminationunloadOneRepository.findPinlaminationunloadOneByPotId(potId);
                        // 创建新的拆解单
                        String orderCode = UniqueCodeUtil.createCode();
                        UnbindingOrder newOrder = new UnbindingOrder();
                        newOrder.setUnbindingOrderCode(orderCode);
                        newOrder.setPotId(potId);
                        newOrder.setCreateTime(LocalDateTime.now());
                        newOrder.setPressMachineId(1);
                        unbindingOrderRepository.save(newOrder);

                        // 创建拆解单明细
                        pinlaminationunloadOnePotList.forEach(
                                unbindingOrder1 -> {
                                    createUnbindingOrderDetail(orderCode, unbindingOrder1.getBarcodeNumber());
                                    unbindingOrder1.setInUnbinding(1);
                                }
                        );
                        pinlaminationunloadOneRepository.saveAllAndFlush(pinlaminationunloadOnePotList);
                    }
                }
            }
        } else if (pressMachineId.equals(2)) {
            List<PinlaminationunloadTwo> pinlaminationunloadTwoList = pinlaminationUnloadTwoRepository.findPinlaminationunloadTwoByBarcodeNumber(scannerValue);
            if (pinlaminationunloadTwoList != null && ! pinlaminationunloadTwoList.isEmpty()) {
                {
                    potId =  pinlaminationunloadTwoList.get(0).getPotId();
                    // 如果 potId 为空，直接抛出异常
                    if (ObjectUtil.isEmpty(potId)) {
                        throw new Exception();
                    }

                    // 查询拆解单
                    unbindingOrder = unbindingOrderRepository.findUnbindingOrderByPotIdAndPressMachineId(potId,pressMachineId);



                    if (ObjectUtil.isEmpty(unbindingOrder)) {

                        //一次性生成完整拆解单
                        List<PinlaminationunloadTwo> pinlaminationunloadTwoPotList = pinlaminationUnloadTwoRepository.findPinlaminationunloadTwoByPotId(potId);
                        // 创建新的拆解单
                        String orderCode = UniqueCodeUtil.createCode();
                        UnbindingOrder newOrder = new UnbindingOrder();
                        newOrder.setUnbindingOrderCode(orderCode);
                        newOrder.setPotId(potId);
                        newOrder.setCreateTime(LocalDateTime.now());
                        newOrder.setPressMachineId(2);
                        unbindingOrderRepository.save(newOrder);

                        // 创建拆解单明细
                        pinlaminationunloadTwoPotList.forEach(
                                unbindingOrder2 -> {
                                    createUnbindingOrderDetail(orderCode, unbindingOrder2.getBarcodeNumber());
                                    unbindingOrder2.setInUnbinding(1);
                                }
                        );
                        pinlaminationUnloadTwoRepository.saveAllAndFlush(pinlaminationunloadTwoPotList);
                    }
                }
            }
        }
    }

    /**
     * 创建拆解单明细
     */
    private void createUnbindingOrderDetail(String orderCode, String scannerValue) {
        UnbindingOrderDetail unbindingOrderDetail = new UnbindingOrderDetail();
        unbindingOrderDetail.setUnbindingOrderCode(orderCode);
        unbindingOrderDetail.setPalletCode(scannerValue);
        unbindingOrderDetail.setCreateTime(LocalDateTime.now());
        unbindingOrderDetail.setInCache(0);
        unbindingOrderDetailRepository.save(unbindingOrderDetail);
    }

    /**
     * 获取缓存架流向
     *
     * @param palletCode
     * @param cacheRackId
     * @return
     */
    public Integer CacheRackFlowTo(String palletCode, Integer cacheRackId) {

        UnbindingOrderDetail unbindingOrderDetail = unbindingOrderDetailRepository.findUnbindingOrderDetailByPalletCode(palletCode);
        if (!ObjectUtil.isEmpty(unbindingOrderDetail)) {
            UnbindingOrder unbindingOrder = unbindingOrderRepository.findUnbindingOrderByUnbindingOrderCode(unbindingOrderDetail.getUnbindingOrderCode());
            String stationName = unbindingOrder.getStationName();
            log.info("该{}载盘要进入的工作台为{}", palletCode,stationName);
            if (cacheRackId.equals(1) && stationName!=null) {
                if (stationName.equals("CacheRack-1")) {
                    updateInCache(palletCode);
                    return 1;
                } else {
                    return 2;
                }
            } else if (cacheRackId.equals(2)&& stationName!=null) {
                if (stationName.equals("CacheRack-2")) {
                    updateInCache(palletCode);
                    return 1;
                } else {
                    return 2;
                }
            }else{
                return 4;
            }
        }else{
            return 3;
        }

    }



    /**
     * 分配拆解台流向
     *
     * @param palletCode 载盘编码
     * @return 流向信息
     */
    public Integer getUnbindingStationFlowTo(String palletCode) {
        UnbindingOrderDetail unbindingOrderDetail = unbindingOrderDetailRepository.findUnbindingOrderDetailByPalletCode(palletCode);
        if (!ObjectUtil.isEmpty(unbindingOrderDetail)) {
            UnbindingOrder unbindingOrder = unbindingOrderRepository.findUnbindingOrderByUnbindingOrderCode(unbindingOrderDetail.getUnbindingOrderCode());
            String stationName = unbindingOrder.getStationName();
            switch (stationName) {
                case "Unbinding-1":
                    return 1;
                case "Unbinding-2":
                    return 2;
                case "Unbinding-3":
                    return 3;
            }
        }
        return null;
    }

    public List<UnbindingOrder> findNotAssignedOrder(){
        return unbindingOrderRepository.findUnbindingOrderByStationName(null);
    }

    public List<UnbindingOrder> findAllUnbindingOrder(){
        return unbindingOrderRepository.findAll();
    }

    @Transactional
    public Integer chooseStation(String unbindingOrderCode, String stationName) {
        UnbindingOrder unbindingOrder = unbindingOrderRepository.findUnbindingOrderByUnbindingOrderCode(unbindingOrderCode);
        UnbindingStation station = unbindingStationRepository.findUnbindingStationByStationName(stationName);
        if (station.getStationStatus().equals(1) && ObjectUtil.isEmpty(station.getUnbindingOrderCode())){
            // 当前工作站为空闲状态
            if (ObjectUtil.isEmpty(unbindingOrder.getStationName())){
                // 选择工作站
                unbindingOrder.setStationName(stationName);
                unbindingOrderRepository.save(unbindingOrder);

                station.setUnbindingOrderCode(unbindingOrderCode);
                station.setStationStatus(2);
                unbindingStationRepository.save(station);
                return 0;
            } else {
                if (station.getStationType().equals(1)){
                    // 该出库单已经选择了进入缓存架
                    return 1;
                }
                // 该出库单已经选择了拆解站
                return 2;
            }
        }else {
            // 工作站有正在作业的拆解单
            return 3;
        }
    }

    @Transactional
    public void deleteDetailOrFinishOrder(String palletCode){
        // 查询拆解单
        String unbindingOrderCode = unbindingOrderDetailRepository
                .findUnbindingOrderDetailByPalletCode(palletCode)
                .getUnbindingOrderCode();

        UnbindingStation station = unbindingStationRepository.findUnbindingStationByUnbindingOrderCode(unbindingOrderCode);

        UnbindingOrderDetail orderDetail = unbindingOrderDetailRepository.findUnbindingOrderDetailByPalletCode(palletCode);

        // 删除该条明细
        unbindingOrderDetailRepository.delete(orderDetail);
        // 强制提交删除操作
        unbindingOrderDetailRepository.flush();

        List<UnbindingOrderDetail> orderDetails = unbindingOrderDetailRepository
                .findUnbindingOrderDetailsByUnbindingOrderCode(unbindingOrderCode);

        if (orderDetails.isEmpty()){
            // 解绑拆解工作站和拆解单
            station.setStationStatus(1);
            station.setUnbindingOrderCode(null);
            unbindingStationRepository.save(station);
        }

    }

    public List<UnbindingStation> getAllStationStatus() {
        // 查找所有拆解单
        return unbindingStationRepository.findAll();
    }

    public List<UnbindingStation> getUnbindingStationStatus() {
        // 查找所有拆解单
        return unbindingStationRepository.findUnbindingStationsByStationType(2);
    }



    public List<CacheRackInfo> getAllCacheRackInfo() {
        List<CacheRackInfo> cacheRackInfoList = new ArrayList<>();
        List<UnbindingStation> cacheRacks = unbindingStationRepository.findUnbindingStationsByStationType(1);
        cacheRacks.forEach(x-> {
            CacheRackInfo cacheRackInfo = new CacheRackInfo();
            cacheRackInfo.setCacheRackName(x.getUiName());
            if (x.getStationStatus().equals(1) && x.getUnbindingOrderCode()==null){
                cacheRackInfo.setOrderDetails(null);
            }
            cacheRackInfo.setOrderDetails(
                    unbindingOrderDetailRepository
                            .findUnbindingOrderDetailsByUnbindingOrderCode(x.getUnbindingOrderCode())
                            .stream()
                            .sorted(Comparator.comparing(UnbindingOrderDetail::getCreateTime).reversed())
                            .collect(Collectors.toList())
            );
            String orderCode =  x.getUnbindingOrderCode();
            if(orderCode != null){
                UnbindingOrder order = unbindingOrderRepository.findUnbindingOrderByUnbindingOrderCode(orderCode);

                // 获取压机名称
                Integer pressMachineId = order.getPressMachineId();
                PressMachine pressMachine = pressMachineRepository.findPressMachineById(pressMachineId);
                cacheRackInfo.setPressMachineName(pressMachine.getMachineName());

                // 获取批次信息
                UnbindingOrderDetail detail = unbindingOrderDetailRepository.findUnbindingOrderDetailsByUnbindingOrderCode(x.getUnbindingOrderCode()).get(0);
                String palletCode = detail.getPalletCode();
                Pallet pallet = palletRepository.findPalletByPalletCode(palletCode);
                Integer processcardId = pallet.getProcesscardId();
                Processcard processcard = processcardRepository.findProcesscardById(processcardId);

                cacheRackInfo.setProcesscardCode(processcard.getProcesscardCode());
                cacheRackInfo.setWorkNum(processcard.getWorkNum());
                cacheRackInfo.setLayerName(processcard.getLayerName());
                cacheRackInfo.setPotId(order.getPotId());
                cacheRackInfo.setUnbindingOrderCode(orderCode);
            }


            cacheRackInfoList.add(cacheRackInfo);
        });
        return cacheRackInfoList;
    }


    @Transactional
    public Integer freeCacheRack(String cacheRackName, String unbindingStationName){
        // try {
        UnbindingStation cacheRackStation = unbindingStationRepository.findUnbindingStationByStationName(cacheRackName);
        List<UnbindingOrderDetail> unbindingOrderDetailList =
                unbindingOrderDetailRepository.findUnbindingOrderDetailsByUnbindingOrderCode(cacheRackStation.getUnbindingOrderCode());

        boolean allInCacheAreOne = unbindingOrderDetailList.stream()
                .allMatch(detail -> detail.getInCache() == 1);

        log.info("分配拆解单信息={}",cacheRackStation.getStationName());
        if (cacheRackStation.getStationName().equals("CacheRack-1")){

            Integer cacheRackStatus = logisticAreaTCP.readHoldingRegisters(RegisterAddressConfig.noOneCacheRackStatus);


            // 当前缓存架没有载盘
            if (cacheRackStation.getStationStatus().equals(1) && ObjectUtil.isEmpty(cacheRackStation.getUnbindingOrderCode()) && cacheRackStatus == 2){
                return 0;
            }
            //载盘没有全进缓存架
            if (!allInCacheAreOne){
                return 3;
            }
            log.info("分配拆解单信息StationStatus={}UnbindingOrderCode={}cacheRackStatus={}",cacheRackStation.getStationStatus(),cacheRackStation.getUnbindingOrderCode(),cacheRackStatus);
            if (cacheRackStation.getStationStatus().equals(2) && !ObjectUtil.isEmpty(cacheRackStation.getUnbindingOrderCode()) && cacheRackStatus != 2 && allInCacheAreOne){
                UnbindingStation unbindingStation = unbindingStationRepository.findUnbindingStationByStationName(unbindingStationName);

                if (!unbindingStation.getStationStatus().equals(1) && !ObjectUtil.isEmpty(unbindingStation.getUnbindingOrderCode())){
                    // 工作站状态为拆解中
                    return 1;
                }
                if (unbindingStation.getStationStatus().equals(1) && ObjectUtil.isEmpty(unbindingStation.getUnbindingOrderCode())){
                    UnbindingOrder unbindingOrder = unbindingOrderRepository.findUnbindingOrderByUnbindingOrderCode(cacheRackStation.getUnbindingOrderCode());
                    unbindingOrder.setStationName(unbindingStationName);
                    unbindingOrderRepository.save(unbindingOrder);
                    // 工作站状态为空闲
                    // 更新拆解站状态
                    unbindingStation.setStationStatus(2);
                    unbindingStation.setUnbindingOrderCode(cacheRackStation.getUnbindingOrderCode());
                    unbindingStationRepository.save(unbindingStation);
                    // 更新缓存架状态
                    cacheRackStation.setStationStatus(1);
                    cacheRackStation.setUnbindingOrderCode(null);
                    unbindingStationRepository.save(cacheRackStation);
                    // 释放缓存架
                    logisticAreaTCP.writeWithRetry(RegisterAddressConfig.noOneFreeCacheRack, 1, 5);
                    log.info("释放缓存架一号,释放信号为={}",logisticAreaTCP.readHoldingRegisters(RegisterAddressConfig.noOneFreeCacheRack));
                    return 2;
                }
            }
        } else if (cacheRackStation.getStationName().equals("CacheRack-2")) {
            Integer cacheRackStatus = logisticAreaTCP.readHoldingRegisters(RegisterAddressConfig.noTwoCacheRackStatus);
            // 当前缓存架没有载盘
            if (cacheRackStation.getStationStatus().equals(1) && ObjectUtil.isEmpty(cacheRackStation.getUnbindingOrderCode()) && cacheRackStatus == 2){
                return 0;
            }
            //载盘没有全进缓存架
            if (!allInCacheAreOne){
                return 3;
            }

            if (cacheRackStation.getStationStatus().equals(2) && !ObjectUtil.isEmpty(cacheRackStation.getUnbindingOrderCode()) && cacheRackStatus != 2 && allInCacheAreOne){
                UnbindingStation unbindingStation = unbindingStationRepository.findUnbindingStationByStationName(unbindingStationName);
                if (!unbindingStation.getStationStatus().equals(1) && !ObjectUtil.isEmpty(unbindingStation.getUnbindingOrderCode())){
                    // 工作站状态为拆解中
                    return 1;
                }
                if (unbindingStation.getStationStatus().equals(1) && ObjectUtil.isEmpty(unbindingStation.getUnbindingOrderCode())){
                    UnbindingOrder unbindingOrder = unbindingOrderRepository.findUnbindingOrderByUnbindingOrderCode(cacheRackStation.getUnbindingOrderCode());
                    unbindingOrder.setStationName(unbindingStationName);
                    unbindingOrderRepository.save(unbindingOrder);
                    // 工作站状态为空闲
                    // 更新拆解站状态
                    unbindingStation.setStationStatus(2);
                    unbindingStation.setUnbindingOrderCode(cacheRackStation.getUnbindingOrderCode());
                    unbindingStationRepository.save(unbindingStation);
                    // 更新缓存架状态
                    cacheRackStation.setStationStatus(1);
                    cacheRackStation.setUnbindingOrderCode(null);
                    unbindingStationRepository.save(cacheRackStation);
                    // 释放缓存架
                    logisticAreaTCP.writeWithRetry(RegisterAddressConfig.noTwoFreeCacheRack, 1, 5);
                    log.info("释放缓存架二号,释放信号为={}",logisticAreaTCP.readHoldingRegisters(RegisterAddressConfig.noTwoFreeCacheRack));
                    return 2;
                }
            }
        }
        return null;
        //} catch (Exception e) {
        //   throw new RuntimeException(e);
        //   }
    }

    public List<UnbindingStation> findCacheRacks(){
        return unbindingStationRepository.findUnbindingStationsByStationType(1);
    }

    @Transactional
    public void updateInCache(String palletCode){
        unbindingOrderDetailRepository.inCache(palletCode);
        log.info("载盘={}已进入缓存架",palletCode);
    }

    public NotAssignedOrderInfo findNotAssignedOrderInfo(UnbindingOrder order){
        NotAssignedOrderInfo notAssignedOrderInfo = new NotAssignedOrderInfo();
        List<UnbindingOrderDetail> details = unbindingOrderDetailRepository.findUnbindingOrderDetailsByUnbindingOrderCode(order.getUnbindingOrderCode());
        String palletCode = details.get(0).getPalletCode();
        Pallet pallet = palletRepository.findPalletByPalletCode(palletCode);
        Processcard processcard = processcardRepository.findProcesscardById(pallet.getProcesscardId());

        List<String> palletCodes = details.stream().map(UnbindingOrderDetail::getPalletCode).collect(Collectors.toList());
        String pressMachineName = pressMachineRepository.findPressMachineById(order.getPressMachineId()).getMachineName();

        notAssignedOrderInfo.setUnbindingOrderCode(details.get(0).getUnbindingOrderCode());
        notAssignedOrderInfo.setPressMachineName(pressMachineName);
        notAssignedOrderInfo.setPotId(order.getPotId());
        notAssignedOrderInfo.setProcesscardCode(processcard.getProcesscardCode());
        notAssignedOrderInfo.setWorkNum(processcard.getWorkNum());
        notAssignedOrderInfo.setLayerName(processcard.getLayerName());
        notAssignedOrderInfo.setPalletCode(palletCodes);
        return notAssignedOrderInfo;
    }

    @Transactional
    public void clearUnbindingStation(String stationName){
        UnbindingStation unbindingStation = unbindingStationRepository.findUnbindingStationByStationName(stationName);
        if(unbindingStation.getUnbindingOrderCode() != null){
            List<UnbindingOrderDetail> unbindingDetailList = unbindingOrderDetailRepository.
                    findUnbindingOrderDetailsByUnbindingOrderCode(unbindingStation.getUnbindingOrderCode());
            //获取该拆解单绑定的所有载盘详细

            unbindingOrderDetailRepository.deleteAll(unbindingDetailList);
            //清除载盘详细
        }

        unbindingStation.setStationStatus(1);
        unbindingStation.setUnbindingOrderCode(null);
        //清除站点绑定信息

        unbindingStationRepository.save(unbindingStation);
    }
}
